package com.ajie.config.security.handler;

import com.ajie.config.security.service.UserDetailServiceImpl;
import com.ajie.utils.TokenUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
@Slf4j
public class JwtAuthenticationFilter extends OncePerRequestFilter {

    @Autowired
    private TokenUtil tokenUtil;

    @Autowired
    private UserDetailServiceImpl detailServiceImpl;

    @Value("${jwt.tokenHeader}")
    private String tokenHeader;

    @Value("${jwt.tokenHead}")
    private String tokenHead;


    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
        
        //1.获取token
        log.info("该文件名是：JwtAuthenticationFilter,该方法是：doFilterInternal");
        String header = request.getHeader(tokenHeader);
        //2.判断token是否存在
        if (null != header && header.startsWith(tokenHead)){
            log.info("token存在");
            //拿到token主体
            String token = header.substring(tokenHead.length());
            //根据token获取用户名
            String usernameByToken = tokenUtil.getUsernameByToken(token);
            //token存在，但是没有登录信息
            if (null != usernameByToken && null == SecurityContextHolder.getContext().getAuthentication()){
                //没有登录信息直接登录
                UserDetails userDetails = detailServiceImpl.loadUserByUsername(usernameByToken);
                //判断token是否有效
                if (!tokenUtil.isExpiration(token) && usernameByToken.equals(userDetails.getUsername())){
                    log.info("token没有过期，并且token取得的用户名和userDetails取得的用户名一致");
                    UsernamePasswordAuthenticationToken  authenticationToken = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                    authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                    SecurityContextHolder.getContext().setAuthentication(authenticationToken);
                }
            }
        }
        //过滤器放行
        chain.doFilter(request,response);
    }
}
